<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherPHP
 * @subpackage   Controllers
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://feather.portalier.com
 * @license      http://www.opensource.org/licenses/mit-license.php The MIT License
 */

class Controller
{
	public $name;
	public $action;
	public $here;
	public $load;
	
	public $admin = false;
	
	public $components = array();
	public $helpers    = array();
	
	// data
	public $params;
	public $data = array();
	
	// model
	public $uses = '';
	public $modelClass;
	
	// view
	public $view;
	public $viewPath;
	public $layout;
	public $defaultLayout = 'default';
	public $autoRender = true;
	
	protected $_viewVars  = array();
	public    $_templates = '';
	
	public    $pageTitle;
	
	/*
	// plugins
	protected $_callbacks;
	*/
	
	
	function __construct($url, $action, &$params)
	{
		$this->name       = str_replace('Controller', '', get_class($this));
		$this->action     = $action;
		$this->here       = $url;
		$this->modelClass = empty($this->uses) ? Inflector::singularize($this->name) : $this->uses;
		$this->viewPath   = Inflector::underscore($this->name);
		
		// loader
		$this->load = Loader::instance('Loader');
		$this->load->autoload($this);
		
		// parameters
		$this->params =& $params;
		$this->params['url']  = cleanArray($_GET);
		$this->params['form'] = cleanArray($_POST);
		$this->params['ajax'] = (env('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
		
		// data
		if (isset($this->params['form']['data'])) {
			$this->data =& $this->params['form']['data'];
		}
	}
	
	// model
	
	function __get($name)
	{
		if ($name == $this->modelClass)
		{
			$this->$name = $this->load->model($name);
			
			if (isset($this->params['args'][0]) and $this->params['args'][0] != 'void')
				$this->$name->id = $this->params['args'][0];
			
			return $this->$name;
		}
	}
	
	// view
	
	function set($left, $right=null)
	{
		if (is_array($left)) $this->_viewVars = array_merge($this->_viewVars, $left);
		else $this->_viewVars[$left] =& $right;
	}
	
	function render($action=null, $layout=null)
	{
		// action
		$action = is_null($action) ? $this->action : $action;
		
		// layout
		if (is_null($layout))
		{
			if (empty($this->layout))
			{
				if ($this->params['bare'])
					$layout = 'bare';
				elseif ($this->params['ajax'])
					$layout = 'ajax';
				else
					$layout = $this->defaultLayout;
			}
			else $layout = $this->layout;
		}
		
		$this->beforeRender();
		
		// view
		if (!isset($this->view))
		{
			require FEATHER.'views'.DS.'view.php';
			$this->view = new View($this);
		}
		
		// render
		$this->view->render($action, $layout, $this->_viewVars);
		$this->afterRender();
		
		$this->autoRender = false;
	}
	
	// redirects & messaging
	
	function flash($mesg, $url='/', $status=null)
	{
		if ($this->params['ajax'])
			echo $mesg;
		else
		{
			if (!DEBUG)
			{
				$this->session->setflash($mesg);
				$this->redirect($url, $status);
			}
			else
			{
				$this->set(array('url' => $url, 'message' => $mesg));
				$this->render('', 'flash');
			}
		}
		exit;
	}
	
	function redirect($url='/', $status=null)
	{
#		if ($status)
#			$this->code($status);
#		if ($this->admin and strpos($url, 'http://') === false and strpos($url, '/admin') !== 0)
#			$url = "/admin$url";
		
		if (!DEBUG)
			header("Location: $url");			
		else
		{
			$this->set(array('url' => $url, 'message' => $url));
			$this->render('', 'flash');
		}
		exit;
	}
	
	function message($title, $message=null)
	{
		$this->set(array('title' => $title, 'message' => $message));
		
		if (!isset($this->view))
			$this->_templates = 'message';
		else
			$this->view->templates = 'message';
		
		$this->render('message');
#		exit;
	}
	
	/*
	// plugins
	function bindAction($action, $plugin, $func)
	{
		$this->_callbacks[$action][$plugin] = $func; 
	}
	
	function callbackActions($action)
	{
		foreach($this->_callbacks[$action] as $plugin => $func) {
			$this->$plugin->$func();
		}
	}
	*/
	
	// callbacks
	
	function beforeAction() {}
	function afterAction()  {}
	
	function beforeRender() {}
	function afterRender()  {}
}
?>